#include <linux/types.h>


#define XDR_BUFFER_SIZE 128
#define MAX_XDR_STRING_SIZE 128
#define TRUE 1
#define FALSE 0

#define XDR_ENCODE 0
#define XDR_DECODE 1

#define MAX_KV_COUNT 256
#define MAX_XDR_RECORDS 256

struct XDR {
        char buffer[XDR_BUFFER_SIZE];
        char pos;
        char op;
	int kvcount;
	int kvlen;
	char pads;
	struct kvec kv[MAX_KV_COUNT];
	struct page *kpages[MAX_KV_COUNT];
	unsigned int residual;
};
typedef struct XDR XDR;

enum ndmp_message {
	NDMP_CONNECT_OPEN = 0x900,
	NDMP_CONNECT_CLIENT_AUTH = 0x901,
	NDMP_CONNECT_CLOSE = 0x902,
	NDMP_CONNECT_SERVER_AUTH = 0x903,
	NDMP_CONFIG_GET_HOST_INFO = 0x100,
	NDMP_CONFIG_GET_CONNECTION_TYPE = 0x102,
	NDMP_CONFIG_GET_AUTH_ATTR = 0x103,
	NDMP_CONFIG_GET_BUTYPE_INFO = 0x104,
	NDMP_CONFIG_GET_FS_INFO = 0x105,
	NDMP_CONFIG_GET_TAPE_INFO = 0x106,
	NDMP_CONFIG_GET_SCSI_INFO = 0x107,
	NDMP_CONFIG_GET_SERVER_INFO = 0x108,
	NDMP_CONFIG_SET_EXT_LIST = 0x109,
	NDMP_CONFIG_GET_EXT_LIST = 0x10A,
	NDMP_SCSI_OPEN = 0x200,
	NDMP_SCSI_CLOSE = 0x201,
	NDMP_SCSI_GET_STATE = 0x202,
	NDMP_SCSI_RESET_DEVICE = 0x204,
	NDMP_SCSI_EXECUTE_CDB = 0x206,
	NDMP_TAPE_OPEN = 0x300,
	NDMP_TAPE_CLOSE = 0x301,
	NDMP_TAPE_GET_STATE = 0x302,
	NDMP_TAPE_MTIO = 0x303,
	NDMP_TAPE_WRITE = 0x304,
	NDMP_TAPE_READ = 0x305,
	NDMP_TAPE_EXECUTE_CDB = 0x307,
	NDMP_DATA_GET_STATE = 0x400,
	NDMP_DATA_START_BACKUP = 0x401,
	NDMP_DATA_START_RECOVER = 0x402,
	NDMP_DATA_ABORT = 0x403,
	NDMP_DATA_GET_ENV = 0x404,
	NDMP_DATA_STOP = 0x407,
	NDMP_DATA_LISTEN = 0x409,
	NDMP_DATA_CONNECT = 0x40A,
	NDMP_DATA_START_RECOVER_FILEHIST = 0x40B,
	NDMP_NOTIFY_DATA_HALTED = 0x501,
	NDMP_NOTIFY_CONNECTION_STATUS = 0x502,
	NDMP_NOTIFY_MOVER_HALTED = 0x503,
	NDMP_NOTIFY_MOVER_PAUSED = 0x504,
	NDMP_NOTIFY_DATA_READ = 0x505,
	NDMP_LOG_FILE = 0x602,
	NDMP_LOG_MESSAGE = 0x603,
	NDMP_FH_ADD_FILE = 0x703,
	NDMP_FH_ADD_DIR = 0x704,
	NDMP_FH_ADD_NODE = 0x705,
	NDMP_MOVER_GET_STATE = 0xA00,
	NDMP_MOVER_LISTEN = 0xA01,
	NDMP_MOVER_CONTINUE = 0xA02,
	NDMP_MOVER_ABORT = 0xA03,
	NDMP_MOVER_STOP = 0xA04,
	NDMP_MOVER_SET_WINDOW = 0xA05,
	NDMP_MOVER_READ = 0xA06,
	NDMP_MOVER_CLOSE = 0xA07,
	NDMP_MOVER_SET_RECORD_SIZE = 0xA08,
	NDMP_MOVER_CONNECT = 0xA09,
	NDMP_EXT_STANDARD_BASE = 0x10000,
	NDMP_EXT_PROPRIETARY_BASE = 0x20000000,
};
typedef enum ndmp_message ndmp_message;

enum ndmp_error {
	NDMP_NO_ERR = 0,
	NDMP_NOT_SUPPORTED_ERR = 1,
	NDMP_DEVICE_BUSY_ERR = 2,
	NDMP_DEVICE_OPENED_ERR = 3,
	NDMP_NOT_AUTHORIZED_ERR = 4,
	NDMP_PERMISSION_ERR = 5,
	NDMP_DEV_NOT_OPEN_ERR = 6,
	NDMP_IO_ERR = 7,
	NDMP_TIMEOUT_ERR = 8,
	NDMP_ILLEGAL_ARGS_ERR = 9,
	NDMP_NO_TAPE_LOADED_ERR = 10,
	NDMP_WRITE_PROTECT_ERR = 11,
	NDMP_EOF_ERR = 12,
	NDMP_EOM_ERR = 13,
	NDMP_FILE_NOT_FOUND_ERR = 14,
	NDMP_BAD_FILE_ERR = 15,
	NDMP_NO_DEVICE_ERR = 16,
	NDMP_NO_BUS_ERR = 17,
	NDMP_XDR_DECODE_ERR = 18,
	NDMP_ILLEGAL_STATE_ERR = 19,
	NDMP_UNDEFINED_ERR = 20,
	NDMP_XDR_ENCODE_ERR = 21,
	NDMP_NO_MEM_ERR = 22,
	NDMP_CONNECT_ERR = 23,
	NDMP_SEQUENCE_NUM_ERR = 24,
	NDMP_READ_IN_PROGRESS_ERR = 25,
	NDMP_PRECONDITION_ERR = 26,
	NDMP_CLASS_NOT_SUPPORTED_ERR = 27,
	NDMP_VERSION_NOT_SUPPORTED_ERR = 28,
	NDMP_EXT_DUPL_CLASSES_ERR = 29,
	NDMP_EXT_DANDN_ILLEGAL_ERR = 30,
};
typedef enum ndmp_error ndmp_error;

enum ndmp_header_message_type {
	NDMP_MESSAGE_REQUEST = 0,
	NDMP_MESSAGE_REPLY = 1,
};
typedef enum ndmp_header_message_type ndmp_header_message_type;

#define NDMP_MESSAGE_POST NDMP_MESSAGE_REQUEST

struct ndmp_header {
	u_long sequence;
	u_long time_stamp;
	ndmp_header_message_type message_type;
	ndmp_message message_code;
	u_long reply_sequence;
	ndmp_error error_code;
};
typedef struct ndmp_header ndmp_header;



enum ndmp_auth_type {
	NDMP_AUTH_NONE = 0,
	NDMP_AUTH_TEXT = 1,
	NDMP_AUTH_MD5 = 2,
};
typedef enum ndmp_auth_type ndmp_auth_type;

struct ndmp_auth_text {
	char *auth_id;
	char *auth_password;
};
typedef struct ndmp_auth_text ndmp_auth_text;

struct ndmp_auth_md5 {
	char *auth_id;
	char auth_digest[16];
};
typedef struct ndmp_auth_md5 ndmp_auth_md5;

struct ndmp_auth_data {
	ndmp_auth_type auth_type;
	union {
		struct ndmp_auth_text auth_text;
		struct ndmp_auth_md5 auth_md5;
	} ndmp_auth_data_u;
};
typedef struct ndmp_auth_data ndmp_auth_data;

struct ndmp_connect_client_auth_request {
	ndmp_auth_data auth_data;
};
typedef struct ndmp_connect_client_auth_request ndmp_connect_client_auth_request;

struct ndmp_connect_client_auth_reply {
	ndmp_error error;
};
typedef struct ndmp_connect_client_auth_reply ndmp_connect_client_auth_reply;

#define NDMP_SCSI_DATA_IN 0x00000001
#define NDMP_SCSI_DATA_OUT 0x00000002

struct ndmp_execute_cdb_request {
	u_long flags;
	u_long timeout;
	u_long datain_len;
	struct {
		u_int cdb_len;
		char *cdb_val;
	} cdb;
	struct {
		u_int dataout_len;
		char *dataout_val;
	} dataout;
};
typedef struct ndmp_execute_cdb_request ndmp_execute_cdb_request;

struct ndmp_execute_cdb_reply {
	ndmp_error error;
	u_char status;
	u_long dataout_len;
	struct {
		u_int datain_len;
		char *datain_val;
	} datain;
	struct {
		u_int ext_sense_len;
		char *ext_sense_val;
	} ext_sense;
};
typedef struct ndmp_execute_cdb_reply ndmp_execute_cdb_reply;

enum ndmp_tape_open_mode {
	NDMP_TAPE_READ_MODE = 0,
	NDMP_TAPE_RDWR_MODE = 1,
	NDMP_TAPE_RAW_MODE = 2,
};
typedef enum ndmp_tape_open_mode ndmp_tape_open_mode;

struct ndmp_tape_open_request {
	char *device;
	ndmp_tape_open_mode mode;
};
typedef struct ndmp_tape_open_request ndmp_tape_open_request;

struct ndmp_tape_open_reply {
	ndmp_error error;
};
typedef struct ndmp_tape_open_reply ndmp_tape_open_reply;

struct ndmp_tape_close_reply {
	ndmp_error error;
};
typedef struct ndmp_tape_close_reply ndmp_tape_close_reply;

struct ndmp_scsi_open_request {
	char *device;
};
typedef struct ndmp_scsi_open_request ndmp_scsi_open_request;

struct ndmp_scsi_open_reply {
	ndmp_error error;
};
typedef struct ndmp_scsi_open_reply ndmp_scsi_open_reply;

struct ndmp_scsi_close_reply {
	ndmp_error error;
};
typedef struct ndmp_scsi_close_reply ndmp_scsi_close_reply;

enum ndmp_connection_status_reason {
        NDMP_CONNECTED = 0,
        NDMP_SHUTDOWN = 1,
        NDMP_REFUSED = 2,
};

typedef enum ndmp_connection_status_reason ndmp_connection_status_reason;
struct ndmp_notify_connection_status_post {
        ndmp_connection_status_reason reason;
        u_short protocol_version;
        char *text_reason;
};
typedef struct ndmp_notify_connection_status_post ndmp_notify_connection_status_post;



char xdr_ndmp_error (XDR *xdrs, ndmp_error *objp);
char xdr_ndmp_header (XDR *xdrs, ndmp_header *objp);
char xdr_ndmp_header_message_type (XDR *xdrs, ndmp_header_message_type *objp);
char xdr_string (XDR *xdrs, char **string);
char xdr_u_long (XDR *xdrs, u_long *i );
char xdr_init (XDR *xdrs, char op);
char xdr_ndmp_message (XDR *xdrs, ndmp_message *objp);
char xdr_ndmp_tape_close_reply (XDR *xdrs, ndmp_tape_close_reply *objp);
char xdr_ndmp_tape_open_reply (XDR *xdrs, ndmp_tape_open_reply *objp);
char xdr_ndmp_tape_open_request (XDR *xdrs, ndmp_tape_open_request *objp, char type);
char xdr_ndmp_connect_client_auth_reply (XDR *xdrs, ndmp_connect_client_auth_reply *objp);
char xdr_ndmp_connect_client_auth_request (XDR *xdrs, ndmp_connect_client_auth_request *objp);
char xdr_ndmp_auth_data (XDR *xdrs, ndmp_auth_data *objp);
char xdr_ndmp_auth_text (XDR *xdrs, ndmp_auth_text *objp);
char xdr_ndmp_auth_type (XDR *xdrs, ndmp_auth_type *objp);
char xdr_ndmp_notify_connection_status_post (XDR *xdrs, ndmp_notify_connection_status_post *objp);
char xdr_ndmp_connection_status_reason (XDR *xdrs, ndmp_connection_status_reason *objp);
char xdr_ndmp_sg (XDR *xdrs, struct scatterlist *sg, int sgcount,int *len);
char xdr_ndmp_execute_cdb_reply (XDR *xdrs, ndmp_execute_cdb_reply *objp, int sgcount);
char xdr_ndmp_execute_cdb_request (XDR *xdrs, ndmp_execute_cdb_request *objp, int sgcount);
char xdr_opaque (XDR *xdrs, char **string, int len);
